package mg.house.WaterFilter;

import javax.swing.text.JTextComponent.KeyBinding;

import utils.DBHandler;

import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.math.Matrix3f;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.Spatial.CullHint;
import com.jme.scene.shape.Box;
import com.jme.scene.shape.Cylinder;
import com.jme.scene.shape.Sphere;
import com.jmex.physics.DynamicPhysicsNode;
import com.jmex.physics.PhysicsSpace;
import com.jmex.physics.StaticPhysicsNode;
import com.jmex.physics.geometry.PhysicsCylinder;
import com.jmex.physics.material.Material;
import com.jmex.physics.util.states.PhysicsGameState;

public class FilterGameState extends PhysicsGameState {
	DBHandler DB = new DBHandler();
	
	private PhysicsSpace physics;
	private int cubelets;
	private int bumpCount = 2;
	private int waterOutput;
	private boolean cubeDropped;
	private boolean cubeControlledByPlayer;
	private boolean isPaused;
	
	private DynamicPhysicsNode waterNode = getPhysicsSpace().createDynamicNode();
	private StaticPhysicsNode bumperNode = getPhysicsSpace().createStaticNode();
	private StaticPhysicsNode container = getPhysicsSpace().createStaticNode();
	private StaticPhysicsNode scoreBoard = getPhysicsSpace().createStaticNode();
	public FilterGameState() {
		super("water filter");
		//Init nodes
		initWaterCube();
		initContainer();
		initBumpers();
		initScoreBoards();
		//controls
		initControls();
		updateNodes();
		physics = PhysicsSpace.create();
		//checkWaterCubeletCount();
		
	}
	
	/*private void checkWaterCubeletCount(){
		if((Integer.parseInt(DB.rawRead("waterCubelet")) == 0)){
			DB.addItem("waterCubelet", 6);
		}
		else {
			cubelets = Integer.parseInt(DB.rawRead("waterCubelet"));
		}
	}*/
	
	private void initScoreBoards(){
		Box sb1 = new Box("sb1", new Vector3f(), 5, 2, 10);
		sb1.getLocalTranslation().set(17, -50, 0);
		sb1.setDefaultColor(ColorRGBA.green);
		scoreBoard.attachChild(sb1);
		
		Box sb2 = new Box("sb2", new Vector3f(), 5, 2, 10);
		sb2.getLocalTranslation().set(-25, -50, 0);
		sb2.setDefaultColor(ColorRGBA.green);
		scoreBoard.attachChild(sb2);
		
		
		rootNode.attachChild(scoreBoard);
	}
	
	private void initBumpers() {
		bumperNode.setMaterial(Material.SPONGE);
		
		Sphere b1 = new Sphere("b1", 8,100,8);
		b1.setLocalScale(1.2f);
		b1.setDefaultColor(ColorRGBA.randomColor());
		bumperNode.attachChild(b1);
		
		Sphere b2 = new Sphere("b2", 8,100,8);
		b2.getLocalTranslation().set(20, -5, 0);
		b2.setDefaultColor(ColorRGBA.randomColor());
		bumperNode.attachChild(b2);
		
		Sphere b3 = new Sphere("b3",8,100,8);
		b3.getLocalTranslation().set(-30, 0, 0);
		b3.setDefaultColor(ColorRGBA.randomColor());
		bumperNode.attachChild(b3);
		
		Sphere b4 = new Sphere("b4", 8, 100, 8);
		b4.getLocalTranslation().set(35, -20,0);
		b4.setDefaultColor(ColorRGBA.randomColor());
		bumperNode.attachChild(b4);
		
		Sphere b5 = new Sphere("b5", 5, 100, 5);
		b5.getLocalTranslation().set(20, 20, 0);
		b5.setDefaultColor(ColorRGBA.randomColor());
		bumperNode.attachChild(b5);
		
		Sphere b6 = new Sphere("b6", 10, 100, 10);
		b6.getLocalTranslation().set(0, -30, 0);
		b6.setDefaultColor(ColorRGBA.randomColor());
		bumperNode.attachChild(b6);
		
		Sphere b7 = new Sphere("b7", 12, 111, 10);
		b7.getLocalTranslation().set(-40, -20, 0);
		b7.setDefaultColor(ColorRGBA.randomColor());
		bumperNode.attachChild(b7);
		
		Sphere b8 = new Sphere("b8", 10, 100, 10);
		b8.getLocalTranslation().set(30, 30, 0);
		b8.setDefaultColor(ColorRGBA.randomColor());
		bumperNode.attachChild(b8);
		
		Sphere b9 = new Sphere("b9", 10, 100, 10);
		b9.getLocalTranslation().set(30, -40, 0);
		b9.setDefaultColor(ColorRGBA.randomColor());
		bumperNode.attachChild(b9);
		
		Sphere b10 = new Sphere("b10", 10, 100, 10);
		b10.getLocalTranslation().set(-25, 30, 0);
		b10.setDefaultColor(ColorRGBA.randomColor());
		bumperNode.attachChild(b10);
		
		Sphere b11 = new Sphere("b11", 10, 100, 10);
		b11.getLocalTranslation().set(2, 30, 0);
		b11.setDefaultColor(ColorRGBA.randomColor());
		bumperNode.attachChild(b11);
		
		Sphere b12 = new Sphere("b12", 5, 100, 5);
		b12.getLocalTranslation().set(-15, -10, 0);
		b12.setDefaultColor(ColorRGBA.randomColor());
		bumperNode.attachChild(b12);
		
		Sphere b13 = new Sphere("b13", 8, 100, 8);
		b13.getLocalTranslation().set(-45,10,0);
		b13.setDefaultColor(ColorRGBA.randomColor());
		bumperNode.attachChild(b13);
		
		Sphere b14 = new Sphere("b14", 5, 100, 5);
		b14.getLocalTranslation().set(-13, 8 ,0);
		b14.setDefaultColor(ColorRGBA.randomColor());
		bumperNode.attachChild(b14);
		
		Sphere b15 = new Sphere("b15", 4, 100, 4);
		b15.getLocalTranslation().set(20, -20,0);
		b15.setDefaultColor(ColorRGBA.randomColor());
		bumperNode.attachChild(b15);
		
		Sphere b16 = new Sphere("b16", 8, 100, 8);
		b16.getLocalTranslation().set(45, -3, 0);
		b16.setDefaultColor(ColorRGBA.randomColor());
		bumperNode.attachChild(b16);
		
		rootNode.attachChild(bumperNode);
		
	}

	private void initContainer() {
		Box leftSideWall = new Box("left side wall",new Vector3f(),2,50,10);
		leftSideWall.getLocalTranslation().setX(-50);
		leftSideWall.setCullHint(CullHint.Always);
		container.attachChild(leftSideWall);
		
		Box rightSideWall = new Box("right side wall", new Vector3f(),2,50,10);
		rightSideWall.getLocalTranslation().setX(50);
		rightSideWall.setCullHint(CullHint.Always);
		container.attachChild(rightSideWall);
		
		Box backWall = new Box("back wall", new Vector3f(),50,50,2);
		backWall.setLocalTranslation(0, 0, -8);
		backWall.setCullHint(CullHint.Always);
		container.attachChild(backWall);
		
		Box frontWall = new Box("front wall", new Vector3f(), 50,50,2);
		frontWall.setLocalTranslation(0,0,8);
		frontWall.setCullHint(CullHint.Always);
		container.attachChild(frontWall);
		
		rootNode.attachChild(container);
	}

	private void initControls() {
		KeyBindingManager.getKeyBindingManager().add("drop", KeyInput.KEY_SPACE);
		KeyBindingManager.getKeyBindingManager().add("x++", KeyInput.KEY_K);
		KeyBindingManager.getKeyBindingManager().add("x--", KeyInput.KEY_H);
		KeyBindingManager.getKeyBindingManager().add("reset", KeyInput.KEY_R);
		KeyBindingManager.getKeyBindingManager().add("bumpx++", KeyInput.KEY_K);
		KeyBindingManager.getKeyBindingManager().add("bumpx--", KeyInput.KEY_H);
		KeyBindingManager.getKeyBindingManager().add("pause", KeyInput.KEY_P);
	}
	
	private void updateControls(float tpf){
		float modifier = 16;
		//TODO Limit movement
		if (cubeDropped == false){
				if (KeyBindingManager.getKeyBindingManager().isValidCommand("x++")){
					waterNode.getLocalTranslation().x += modifier * tpf;
					}
				else if (KeyBindingManager.getKeyBindingManager().isValidCommand("x--")){
					waterNode.getLocalTranslation().x -= modifier * tpf;
					}
				if (KeyBindingManager.getKeyBindingManager().isValidCommand("drop")){
					System.out.println("hi");
					waterNode.setAffectedByGravity(true);
					cubeDropped = true;
					}
				}
		//debug code
		else if (cubeDropped = true){
			if (KeyBindingManager.getKeyBindingManager().isValidCommand("reset")){
				resetWaterCube();
			}
			if (bumpCount > 0){
				if(KeyBindingManager.getKeyBindingManager().isValidCommand("bumpx++",false)){
					waterNode.addForce(new Vector3f(300,600,0));
					bumpCount--;
					System.out.println("bump = " +bumpCount);
				}
				
				else if(KeyBindingManager.getKeyBindingManager().isValidCommand("bumpx--",false)){
					waterNode.addForce(new Vector3f(-300,600,0));
					bumpCount--;
					System.out.println("bump = " +bumpCount);
				}

		}
		}
		
		if (KeyBindingManager.getKeyBindingManager().isValidCommand("pause",false)){
			if (isPaused){
				this.active = true;
			}
			else {
				this.active = false;
			}
		}
		
	}
	

	private void updateNodes() {
		//Update the root node.
		rootNode.updateModelBound();
		rootNode.updateRenderState();
		rootNode.updateGeometricState(0,true);
		//Update physic node
		waterNode.generatePhysicsGeometry();
		container.generatePhysicsGeometry();
		bumperNode.generatePhysicsGeometry();
		scoreBoard.generatePhysicsGeometry();
	}

	private void initWaterCube() {
		Box waterCube = new Box("water cube", new Vector3f(), 1,1,1);
		waterCube.setDefaultColor(ColorRGBA.blue);
		waterNode.attachChild(waterCube);
		waterNode.setAffectedByGravity(false);
		waterNode.getLocalTranslation().setY(50);
		rootNode.attachChild(waterNode);
	}
	
	/**
	 * Method for figuring out if the cubelet is in a scoring area or needs to be reset
	 */
	private void updateWaterStatus(){		
		System.out.println(waterNode.getLocalTranslation().y);
		if (scoreBoard.hasCollision(waterNode, true)){
			if (bumpCount > 0){
				waterOutput *= bumpCount + 1;
				System.out.println(waterOutput);
			}
			else {
				waterOutput += 1;
			}
		}
		
		else if (waterNode.getLocalTranslation().y < -60){
			resetWaterCube();
		}
	}
	
	private void resetWaterCube(){
		waterNode.getLocalTranslation().set(0, 50, 0);
		waterNode.setAffectedByGravity(false);
		waterNode.setLocalRotation(new Matrix3f());
		waterNode.clearDynamics();
		cubeDropped = false;
		bumpCount = 2;
		cubelets--;
		//TODO Support on screen gui
		System.out.println("Cubelets = " + cubelets);
	}
	
	public void update(float tpf) {
        //Update root node's location on items
        updateControls(tpf);
        super.update(tpf);
        updateWaterStatus();
	}
	
	public void cleanUp(){
		//TODO log cubelets to the DB
	}
	
}
